package com.zbzly.reactive.reactiverbac.handler;

import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;

@Component
public class ReactiveServerAuthenticationFailureHandler implements ServerAuthenticationFailureHandler {
    @Override
    public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) {
        ServerHttpResponse response = webFilterExchange.getExchange().getResponse();
        HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
        switch (exception) {
            case UsernameNotFoundException ignored -> objectObjectHashMap.put("error", "Username not found");
            case BadCredentialsException ignored -> objectObjectHashMap.put("error", "Bad credentials");
            case LockedException ignored -> objectObjectHashMap.put("error", "Locked");
            case null, default -> {
                if (exception != null) {
                    objectObjectHashMap.put("error", exception.getMessage());
                }
            }
        }
        DataBuffer buffer = response.bufferFactory().wrap(objectObjectHashMap.toString().getBytes(StandardCharsets.UTF_8));
        return response.writeWith(Mono.just(buffer));
    }
}
